
using ILRuntime.Runtime.Intepreter;
using System;
using System.Collections.Generic;
using System.IO;
using GameFramework;
using ILRuntime.Runtime.Generated;
using UnityEngine;
using UnityEngine.Events;
using AppDomain = ILRuntime.Runtime.Enviorment.AppDomain;

namespace StarForce
{
    public static class ILRuntimeHelper
    {
        public static void InitILRuntime(AppDomain appDomain)
        {
            //TODO:注册重定向方法

            //TODO:适配委托

            //GF用
            appDomain.DelegateManager.RegisterMethodDelegate<float>();
            appDomain.DelegateManager.RegisterMethodDelegate<object, ILTypeInstance>();
            appDomain.DelegateManager.RegisterMethodDelegate<object, GameFramework.Event.GameEventArgs>();
            appDomain.DelegateManager.RegisterMethodDelegate<UnityEngine.Vector2>();
            appDomain.DelegateManager.RegisterFunctionDelegate<ILRuntime.Runtime.Intepreter.ILTypeInstance, ILRuntime.Runtime.Intepreter.ILTypeInstance, System.Int32>();
            appDomain.DelegateManager.RegisterFunctionDelegate<System.Single>();
            appDomain.DelegateManager.RegisterFunctionDelegate<System.Int32>();
            appDomain.DelegateManager.RegisterMethodDelegate<System.Int32>();
            appDomain.DelegateManager.RegisterMethodDelegate<System.Boolean, System.String>();
            appDomain.DelegateManager.RegisterMethodDelegate<UnityEngine.GameObject, System.Int32>();
            appDomain.DelegateManager.RegisterMethodDelegate<GameFramework.Network.INetworkChannel>();
            appDomain.DelegateManager.RegisterMethodDelegate<System.String, GameFramework.Resource.LoadResourceStatus, System.String, System.Object>();
            appDomain.DelegateManager.RegisterMethodDelegate<DigitsNFCToolkit.NDEFPushResult>();
            appDomain.DelegateManager.RegisterMethodDelegate<DigitsNFCToolkit.NDEFReadResult>();
            appDomain.DelegateManager.RegisterMethodDelegate<DigitsNFCToolkit.NDEFWriteResult>();
            
            appDomain.DelegateManager.RegisterDelegateConvertor<UnityEngine.Events.UnityAction<UnityEngine.Vector2>>((act) =>
            {
                return new UnityEngine.Events.UnityAction<UnityEngine.Vector2>((arg0) =>
                {
                    ((Action<UnityEngine.Vector2>)act)(arg0);
                });
            });


            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.GameFrameworkAction>((act) =>
            {
                return new GameFramework.GameFrameworkAction(() =>
                {
                    ((Action)act)();
                });
            });

            
            appDomain.DelegateManager.RegisterDelegateConvertor<UnityAction<DigitsNFCToolkit.NDEFPushResult>>(action =>
            {
                return new UnityAction<DigitsNFCToolkit.NDEFPushResult>((a) =>
                {
                    ((Action<DigitsNFCToolkit.NDEFPushResult>)action)(a);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<UnityAction<DigitsNFCToolkit.NDEFReadResult>>(action =>
            {
                return new UnityAction<DigitsNFCToolkit.NDEFReadResult>((a) =>
                {
                    ((Action<DigitsNFCToolkit.NDEFReadResult>)action)(a);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<UnityAction<DigitsNFCToolkit.NDEFWriteResult>>(action =>
            {
                return new UnityAction<DigitsNFCToolkit.NDEFWriteResult>((a) =>
                {
                    ((Action<DigitsNFCToolkit.NDEFWriteResult>)action)(a);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.Resource.LoadAssetFailureCallback>((act) =>
            {
                return new GameFramework.Resource.LoadAssetFailureCallback((assetName, status, errorMessage, userData) =>
                {
                    ((Action<System.String, GameFramework.Resource.LoadResourceStatus, System.String, System.Object>)act)(assetName, status, errorMessage, userData);
                });
            });

            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.GameFrameworkAction<GameFramework.Network.INetworkChannel>>((act) =>
            {
                return new GameFramework.GameFrameworkAction<GameFramework.Network.INetworkChannel>((obj) =>
                {
                    ((Action<GameFramework.Network.INetworkChannel>)act)(obj);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<System.Comparison<ILRuntime.Runtime.Intepreter.ILTypeInstance>>((act) =>
            {
                return new System.Comparison<ILRuntime.Runtime.Intepreter.ILTypeInstance>((x, y) =>
                {
                    return ((Func<ILRuntime.Runtime.Intepreter.ILTypeInstance, ILRuntime.Runtime.Intepreter.ILTypeInstance, System.Int32>)act)(x, y);
                });
            });

            //PB用
//            appDomain.DelegateManager.RegisterFunctionDelegate<IMessageAdaptor.Adaptor>();
//            appDomain.DelegateManager.RegisterMethodDelegate<IMessageAdaptor.Adaptor>();


            //TODO:注册委托
            appDomain.DelegateManager.RegisterDelegateConvertor<UnityAction>((action) =>
            {
                return new UnityAction(() =>
                {
                    ((Action)action)();
                });
            });

            appDomain.DelegateManager.RegisterDelegateConvertor<UnityAction<float>>((action) =>
            {
                return new UnityAction<float>((a) =>
                {
                    ((Action<float>)action)(a);
                });
            });

            appDomain.DelegateManager.RegisterDelegateConvertor<EventHandler<GameFramework.Event.GameEventArgs>>((act) =>
            {
                return new EventHandler<GameFramework.Event.GameEventArgs>((sender, e) =>
                {
                    ((Action<object, GameFramework.Event.GameEventArgs>)act)(sender, e);
                });
            });

            appDomain.DelegateManager.RegisterDelegateConvertor<EventHandler<ILTypeInstance>>((act) =>
            {
                return new EventHandler<ILTypeInstance>((sender, e) =>
                {
                    ((Action<object, ILTypeInstance>)act)(sender, e);
                });
            });
            
            //todo 资源加载委托
            appDomain.DelegateManager.RegisterMethodDelegate<System.String, System.Object, System.Single, System.Object>();
            appDomain.DelegateManager.RegisterMethodDelegate<System.String, System.Single, System.Object>();


            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.Resource.LoadAssetSuccessCallback>((act) =>
            {
                return new GameFramework.Resource.LoadAssetSuccessCallback((assetName, asset, duration, userData) =>
                {
                    ((Action<System.String, System.Object, System.Single, System.Object>)act)(assetName, asset, duration, userData);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.Resource.LoadAssetUpdateCallback>((act) =>
            {
                return new GameFramework.Resource.LoadAssetUpdateCallback((assetName, progress, userData) =>
                {
                    ((Action<System.String, System.Single, System.Object>)act)(assetName, progress, userData);
                });
            });
            appDomain.DelegateManager.RegisterMethodDelegate<System.String>();

            appDomain.DelegateManager.RegisterDelegateConvertor<UnityEngine.Events.UnityAction<System.String>>((act) =>
            {
                return new UnityEngine.Events.UnityAction<System.String>((arg0) =>
                {
                    ((Action<System.String>)act)(arg0);
                });
            });
            
            appDomain.DelegateManager.RegisterMethodDelegate<GameFramework.Network.INetworkChannel, System.Object>();
            appDomain.DelegateManager.RegisterDelegateConvertor<GameFramework.GameFrameworkAction<GameFramework.Network.INetworkChannel, System.Object>>((act) =>
            {
                return new GameFramework.GameFrameworkAction<GameFramework.Network.INetworkChannel, System.Object>((arg1, arg2) =>
                {
                    ((Action<GameFramework.Network.INetworkChannel, System.Object>)act)(arg1, arg2);
                });
            });

            appDomain.DelegateManager.RegisterMethodDelegate<UnityEngine.EventSystems.PointerEventData>();

            //dotween
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.Core.DOGetter<System.Single>>((act) =>
            {
                return new DG.Tweening.Core.DOGetter<System.Single>(() =>
                {
                    return ((Func<System.Single>)act)();
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.Core.DOSetter<System.Single>>((act) =>
            {
                return new DG.Tweening.Core.DOSetter<System.Single>((pNewValue) =>
                {
                    ((Action<System.Single>)act)(pNewValue);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.TweenCallback>((act) =>
            {
                return new DG.Tweening.TweenCallback(() =>
                {
                    ((Action)act)();
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.Core.DOGetter<System.Int32>>((act) =>
            {
                return new DG.Tweening.Core.DOGetter<System.Int32>(() =>
                {
                    return ((Func<System.Int32>)act)();
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.Core.DOSetter<System.Int32>>((act) =>
            {
                return new DG.Tweening.Core.DOSetter<System.Int32>((pNewValue) =>
                {
                    ((Action<System.Int32>)act)(pNewValue);
                });
            });
            
            appDomain.DelegateManager.RegisterDelegateConvertor<DG.Tweening.TweenCallback>((act) =>
            {
                return new DG.Tweening.TweenCallback(() =>
                {
                    ((Action)act)();
                });
            });

            //注册CLR绑定代码
            CLRBindings.Initialize(appDomain);

            //TODO:注册跨域继承适配器
            appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter());
//            appDomain.RegisterCrossBindingAdaptor(new IMessageAdaptor());
//            appDomain.RegisterCrossBindingAdaptor(new IDisposableAdaptor());
//            appDomain.RegisterCrossBindingAdaptor(new IAsyncStateMachineAdaptor());

            //TODO:注册值类型绑定
            appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
            appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
            appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder());

            //注册LitJson
            LitJson.JsonMapper.RegisterILRuntimeCLRRedirection(appDomain);
        }
    }
}

